﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SPMS.Commons.Configuration;
using SPMS.Utility;
using SPMS.Log.Configuration.Handler;

namespace SPMS.Log.Configuration
{
    /// <summary>
    /// 节点处理器注册类
    /// </summary>
    /// <remarks>定义了节点处理器注册类</remarks>
    /// <history>
    /// [zanezeng]   2008-12-15 14:10    Created
    /// </history>
    public sealed class NodeHandlerRegistry : INodeHandlerRegistry
    {
        #region ---Constructor

        /// <summary>
        /// 初始化类型<see cref="NodeHandlerRegistry"/>的新实例
        /// </summary>
        /// <remarks></remarks>
        /// <history>
        /// [ZaneZeng]               2009-5-21 9:11    创建
        /// </history>
        public NodeHandlerRegistry()
        {
            //创建节点处理器字典
            this.m_NodeHandlers = new Dictionary<string, IConfigurationNodeHandler<ParseContext>>( StringComparer.InvariantCultureIgnoreCase );
        }

        #endregion

        #region ---INodeHandlerRegistry

        /// <summary>
        /// 通过指定的标记获得或者设置标签解析器
        /// </summary>
        /// <value>标签解析器</value>
        /// <remarks></remarks>
        /// <exception cref="ArgumentNullException">设置标记时<param name="tagName">为Null或者为空字符串</param></exception>
        /// <exception cref="ArgumentNullException">设置标记时<paramref name="value"/>为Null</exception>
        /// <history>
        /// [zanezeng]   2008-11-17 8:48    Created
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-11-17 9:53    Created
        /// </history>
        public IConfigurationNodeHandler<ParseContext> this[string tagName]
        {
            get
            {
                //用于保存结果
                IConfigurationNodeHandler<ParseContext> handler = null;

                //尝试取得
                if (this.m_NodeHandlers.TryGetValue( tagName, out handler ))
                {
                    //返回
                    return handler;
                }

                //默认返回Null
                return null;
            }
            set
            {
                //断言参数
                ArgumentAssert.AssertStringArgumentNotNullOrEmpty( tagName, "tagName" );
                ArgumentAssert.AssertArgumentNotNull( value, "value" );

                //保存节点处理器
                this.m_NodeHandlers[tagName] = value;
            }
        }

        /// <summary>
        /// 注册节点处理器
        /// </summary>
        /// <param name="tagName">配置标记名称</param>
        /// <param name="handler">需要注册的节点处理器</param>
        /// <remarks></remarks>
        /// <exception cref="System.ArgumentNullException"><paramref name="tagName"/>为Null或者为空字符串</exception>
        /// <exception cref="System.ArgumentNullException"><paramref name="handler"/>为Null</exception>
        /// <exception cref="System.ArgumentException"><paramref name="tagName"/>指定的标记名名称已经注册</exception>
        /// <history>
        /// [zanezeng]   2008-11-17 8:44    Created
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-11-17 9:53    Created
        /// </history>
        public void RegisterNodeHandler( string tagName, IConfigurationNodeHandler<ParseContext> handler )
        {
            //断言参数
            ArgumentAssert.AssertStringArgumentNotNullOrEmpty( tagName, "tagName" );
            ArgumentAssert.AssertArgumentNotNull( handler, "handler" );

            //判断标记名称是否已经注册
            if (this.m_NodeHandlers.ContainsKey( tagName ))
            {
                //抛出异常
                throw new ArgumentException( string.Format( Properties.Resources.MSG_TAG_HANDLER_REDUPLICATE, tagName ), "tagName" );
            }

            //注册
            this.m_NodeHandlers[tagName] = handler;
        }

        #endregion

        #region ---IConfigurationNodeHandlerFactory<ParseContext>

        /// <summary>
        /// 获得指定节点的节点处理器
        /// </summary>
        /// <param name="node">需要处理的配置节点</param>
        /// <returns>节点处理器</returns>
        /// <remarks>如果指定的节点处理器没有找到，则返回Null</remarks>
        /// <history>
        /// [zanezeng]   2008-11-17 9:16    Created
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-11-17 9:53    Created
        /// </history>
        public IConfigurationNodeHandler<ParseContext> GetNodeHandler( IConfigurationNode node )
        {
            //判断是否为Null
            if (null == node)
            {
                //返回Null
                return null;
            }

            //返回节点处理器
            return this[node.Name];
        }

        #endregion

        #region ---Property

        /// <summary>
        /// 获得默认节点注册
        /// </summary>
        /// <value>默认节点注册</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-12-15 14:17    Created
        /// </history>
        public static INodeHandlerRegistry Default
        {
            get
            {
                //判断是否初始化
                if (null != s_Default)
                {
                    //如果已经初始化，则直接返回
                    return s_Default;
                }

                lock (s_SyncRoot)
                {
                    //判断是否初始化
                    if (null != s_Default)
                    {
                        //返回
                        return s_Default;
                    }

                    //创建
                    NodeHandlerRegistry registry = new NodeHandlerRegistry();

                    //注册日志追加器节点处理器
                    registry.RegisterNodeHandler( LogConfiguationTags.TAG_APPENDER, new Appender_NodeHandler() );
                    //注册日志追加器参照节点处理器
                    registry.RegisterNodeHandler( LogConfiguationTags.TAG_APPENDER_REF, new AppenderRef_NodeHandler() );
                    //注册日志追加器组节点处理器
                    registry.RegisterNodeHandler( LogConfiguationTags.TAG_APPENDERS, new Appenders_NodeHandler() );
                    //处理过滤器节点处理器
                    registry.RegisterNodeHandler( LogConfiguationTags.TAG_FILTER, new Filter_NodeHandler() );
                    //注册配置根节点标记
                    registry.RegisterNodeHandler( LogConfiguationTags.TAG_LEYSER_LOG, new LeyserLog_NodeHandler() );
                    //注册日志记录器节点处理器
                    registry.RegisterNodeHandler( LogConfiguationTags.TAG_LOGGER, new Logger_NodeHandler() );
                    //注册日志记录器组节点处理器
                    registry.RegisterNodeHandler( LogConfiguationTags.TAG_LOGGERS, new Loggers_NodeHandler() );
                    //注册属性节点处理器
                    registry.RegisterNodeHandler( LogConfiguationTags.TAG_PROPERTY, new Property_NodeHandler() );

                    //设置为默认节点处理器注册
                    s_Default = registry;

                    //返回
                    return s_Default;
                }
            }
        }

        #endregion

        #region ---Field

        /// <summary>
        /// 节点处理器字典
        /// </summary>
        private Dictionary<string, IConfigurationNodeHandler<ParseContext>> m_NodeHandlers;

        /// <summary>
        /// 默认节点注册
        /// </summary>
        private static NodeHandlerRegistry s_Default = null;

        /// <summary>
        /// 同步对象
        /// </summary>
        private static readonly object s_SyncRoot = new object();

        #endregion
    }
}
